<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
	<meta name="keywords" content="fescar、seata、分布式事务" />
	<meta name="description" content="从 0 开始入门 Seata，搭建 Seata 服务，并接入 Java 项目中实现分布式事务" />
	<!-- 网页标签标题 -->
	<title>Seata 极简入门</title>
  <link rel="shortcut icon" href="/img/seata_logo_small.jpeg"/>
	<link rel="stylesheet" href="/build/blogDetail.css" />
</head>
<body>
	<div id="root"><div class="blog-detail-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/zh-cn/index.html"><img class="logo" src="//img.alicdn.com/tfs/TB1gqL1w4D1gK0jSZFyXXciOVXa-1497-401.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="https://img.alicdn.com/tfs/TB14eEmw7P2gK0jSZPxXXacQpXa-38-32.png"/><ul><li class="menu-item menu-item-normal"><a href="/zh-cn/index.html" target="_self">首页</a></li><li class="menu-item menu-item-normal"><a href="/zh-cn/docs/overview/what-is-seata.html" target="_self">文档</a></li><li class="menu-item menu-item-normal"><a href="/zh-cn/docs/developers/developers_dev.html" target="_self">开发者</a></li><li class="menu-item menu-item-normal menu-item-normal-active"><a href="/zh-cn/blog/index.html" target="_self">博客</a></li><li class="menu-item menu-item-normal"><a href="/zh-cn/community/index.html" target="_self">社区</a></li><li class="menu-item menu-item-normal"><a href="/zh-cn/blog/download.html" target="_self">下载</a></li></ul></div></div></header><section class="blog-content markdown-body"><ul>
<li><a href="#">1. 概述</a></li>
<li><a href="#">2. 部署单机 TC Server</a></li>
<li><a href="#">3. 部署集群 TC Server</a></li>
<li><a href="#">4. 接入 Java 应用</a></li>
</ul>
<h1>1. 概述</h1>
<p><a href="https://github.com/seata/seata">Seata</a> 是<strong>阿里</strong>开源的一款开源的<strong>分布式事务</strong>解决方案，致力于提供高性能和简单易用的分布式事务服务。</p>
<h2>1.1 四种事务模式</h2>
<p>Seata 目标打造<strong>一站式</strong>的分布事务的解决方案，最终会提供四种事务模式：</p>
<ul>
<li>AT 模式：参见<a href="https://seata.io/zh-cn/docs/dev/mode/at-mode.html">《Seata AT 模式》</a>文档</li>
<li>TCC 模式：参见<a href="https://seata.io/zh-cn/docs/dev/mode/tcc-mode.html">《Seata TCC 模式》</a>文档</li>
<li>Saga 模式：参见<a href="https://seata.io/zh-cn/docs/dev/mode/saga-mode.html">《SEATA Saga 模式》</a>文档</li>
<li>XA 模式：正在开发中...</li>
</ul>
<p>目前使用的<strong>流行度</strong>情况是：AT &gt; TCC &gt; Saga。因此，我们在学习 Seata 的时候，可以花更多精力在 <strong>AT 模式</strong>上，最好搞懂背后的实现原理，毕竟分布式事务涉及到数据的正确性，出问题需要快速排查定位并解决。</p>
<blockquote>
<p>友情提示：具体的流行度，胖友可以选择看看 <a href="https://github.com/seata/seata/issues/1246">Wanted: who's using Seata</a> 每个公司登记的使用方式。</p>
</blockquote>
<h2>1.2 三种角色</h2>
<p>在 Seata 的架构中，一共有三个角色：</p>
<p><img src="http://www.iocoder.cn/images/Seata/2017-01-01/02.png" alt="三个角色"></p>
<ul>
<li><strong>TC</strong> (Transaction Coordinator) - 事务协调者：维护全局和分支事务的状态，驱动<strong>全局事务</strong>提交或回滚。</li>
<li><strong>TM</strong> (Transaction Manager) - 事务管理器：定义<strong>全局事务</strong>的范围，开始全局事务、提交或回滚全局事务。</li>
<li><strong>RM</strong> ( Resource Manager ) - 资源管理器：管理<strong>分支事务</strong>处理的资源( Resource )，与 TC 交谈以注册分支事务和报告分支事务的状态，并驱动<strong>分支事务</strong>提交或回滚。</li>
</ul>
<p>其中，TC 为单独部署的 <strong>Server</strong> 服务端，TM 和 RM 为嵌入到应用中的 <strong>Client</strong> 客户端。</p>
<p>在 Seata 中，一个分布式事务的<strong>生命周期</strong>如下：</p>
<p><img src="http://www.iocoder.cn/images/Seata/2017-01-01/01.png" alt="架构图"></p>
<blockquote>
<p>友情提示：看下艿艿添加的红色小勾。</p>
</blockquote>
<ul>
<li>
<p>TM 请求 TC 开启一个全局事务。TC 会生成一个 <strong>XID</strong> 作为该全局事务的编号。</p>
<blockquote>
<p><strong>XID</strong>，会在微服务的调用链路中传播，保证将多个微服务的子事务关联在一起。</p>
</blockquote>
</li>
<li>
<p>RM 请求 TC 将本地事务注册为全局事务的分支事务，通过全局事务的 <strong>XID</strong> 进行关联。</p>
</li>
<li>
<p>TM 请求 TC 告诉 <strong>XID</strong> 对应的全局事务是进行提交还是回滚。</p>
</li>
<li>
<p>TC 驱动 RM 们将 <strong>XID</strong> 对应的自己的本地事务进行提交还是回滚。</p>
</li>
</ul>
<h2>1.3 框架支持情况</h2>
<p>Seata 目前提供了对主流的<strong>微服务框架</strong>的支持：</p>
<ul>
<li>
<p>Dubbo</p>
<blockquote>
<p>通过 <a href="https://github.com/seata/seata/blob/develop/integration/dubbo/"><code>seata-dubbo</code></a> 集成</p>
</blockquote>
</li>
<li>
<p>SOFA-RPC</p>
<blockquote>
<p>通过 <a href="https://github.com/seata/seata/blob/develop/integration/sofa-rpc/"><code>seata-sofa-rpc</code></a> 集成</p>
</blockquote>
</li>
<li>
<p>Motan</p>
<blockquote>
<p>通过 <a href="https://github.com/seata/seata/blob/develop/integration/motan/"><code>seata-motan</code></a> 集成</p>
</blockquote>
</li>
<li>
<p>gRPC</p>
<blockquote>
<p>通过 <a href="https://github.com/seata/seata/blob/develop/integration/gprc/"><code>seata-grpc</code></a> 集成</p>
</blockquote>
</li>
<li>
<p>Apache HttpClient</p>
<blockquote>
<p>通过 <a href="https://github.com/seata/seata/blob/develop/integration/http/"><code>seata-http</code></a> 集成</p>
</blockquote>
</li>
<li>
<p>Spring Cloud OpenFeign</p>
<blockquote>
<p>通过 <a href="https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-seata/src/main/java/com/alibaba/cloud/seata/"><code>spring-cloud-starter-alibaba-seata</code></a> 的 <a href="https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-seata/src/main/java/com/alibaba/cloud/seata/feign/"><code>feign</code></a> 模块</p>
</blockquote>
</li>
<li>
<p>Spring RestTemplate</p>
<blockquote>
<p>通过 <a href="https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-seata/src/main/java/com/alibaba/cloud/seata/feign/SeataBeanPostProcessor.java"><code>spring-cloud-starter-alibaba-seata</code></a> 的 <a href="https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-seata/src/main/java/com/alibaba/cloud/seata/rest/"><code>rest</code></a> 模块</p>
</blockquote>
</li>
</ul>
<p>同时方便我们集成到 Java 项目当中，Seata 也提供了相应的 Starter 库：</p>
<ul>
<li><a href="https://mvnrepository.com/artifact/io.seata/seata-spring-boot-starter"><code>seata-spring-boot-starter</code></a></li>
<li><a href="https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-seata"><code>spring-cloud-starter-alibaba-seata</code></a></li>
</ul>
<p>因为 Seata 是基于 <a href="https://docs.oracle.com/javase/7/docs/api/javax/sql/DataSource.html">DataSource</a> 数据源进行<strong>代理</strong>来拓展，所以天然对主流的 ORM 框架提供了非常好的支持：</p>
<ul>
<li>MyBatis、MyBatis-Plus</li>
<li>JPA、Hibernate</li>
</ul>
<h2>1.4 案例情况</h2>
<p>从 <a href="https://github.com/seata/seata/issues/1246">Wanted: who's using Seata</a> 的登记情况，Seata 已经在国内很多团队开始落地，其中不乏有滴滴、韵达等大型公司。可汇总如下图：</p>
<p><img src="http://www.iocoder.cn/images/Seata/2017-01-01/03.png" alt="汇总图"></p>
<p>另外，在 <a href="https://github.com/seata/awesome-seata">awesome-seata</a> 仓库中，艿艿看到了滴滴等等公司的落地时的技术分享，还是非常真实可靠的。如下图所示：<img src="http://www.iocoder.cn/images/Seata/2017-01-01/04.png" alt="awesome-seata 滴滴"></p>
<p>从案例的情况来说，Seata 可能给是目前已知最可靠的分布式事务解决方案，至少对它进行技术投入是非常不错的选择。</p>
<h1>2. 部署单机 TC Server</h1>
<p>本小节，我们来学习部署<strong>单机</strong> Seata <strong>TC</strong> Server，常用于学习或测试使用，不建议在生产环境中部署单机。</p>
<p>因为 TC 需要进行全局事务和分支事务的记录，所以需要对应的<strong>存储</strong>。目前，TC 有两种存储模式( <code>store.mode</code> )：</p>
<ul>
<li>file 模式：适合<strong>单机</strong>模式，全局事务会话信息在<strong>内存</strong>中读写，并持久化本地文件 <code>root.data</code>，性能较高。</li>
<li>db 模式：适合<strong>集群</strong>模式，全局事务会话信息通过 <strong>db</strong> 共享，相对性能差点。</li>
</ul>
<p>显然，我们将采用 file 模式，最终我们部署单机 TC Server 如下图所示：<img src="http://www.iocoder.cn/images/Seata/2017-01-01/11.png" alt="单机 TC Server"></p>
<p>哔哔完这么多，我们开始正式部署单机 TC Server，这里艿艿使用 macOS 系统，和 Linux、Windows 是差不多的，胖友脑补翻译。</p>
<h2>2.1 下载 Seata 软件包</h2>
<p>打开 <a href="https://github.com/seata/seata/releases">Seata 下载页面</a>，选择想要的 Seata 版本。这里，我们选择 <a href="https://github.com/seata/seata/releases/tag/v1.1.0">v1.1.0</a> 最新版本。</p>
<pre><code class="language-Bash"><span class="hljs-comment"># 创建目录</span>
$ mkdir -p /Users/yunai/Seata
$ <span class="hljs-built_in">cd</span> /Users/yunai/Seata

<span class="hljs-comment"># 下载</span>
$ wget https://github.com/seata/seata/releases/download/v1.1.0/seata-server-1.1.0.tar.gz

<span class="hljs-comment"># 解压</span>
$ tar -zxvf seata-server-1.1.0.tar.gz

<span class="hljs-comment"># 查看目录</span>
$ <span class="hljs-built_in">cd</span> seata
$ ls -ls
24 -rw-r--r--    1 yunai  staff  11365 May 13  2019 LICENSE
 0 drwxr-xr-x    4 yunai  staff    128 Apr  2 07:46 bin <span class="hljs-comment"># 执行脚本</span>
 0 drwxr-xr-x    9 yunai  staff    288 Feb 19 23:49 conf <span class="hljs-comment"># 配置文件</span>
 0 drwxr-xr-x  138 yunai  staff   4416 Apr  2 07:46 lib <span class="hljs-comment">#  seata-*.jar + 依赖库 </span>
</code></pre>
<h2>2.2 启动 TC Server</h2>
<p>执行 <code>nohup sh bin/seata-server.sh &amp;</code> 命令，启动 TC Server 在后台。在 <code>nohup.out</code> 文件中，我们看到如下日志，说明启动成功：</p>
<pre><code class="language-Java"># 使用 File 存储器
2020-04-02 08:36:01.302 INFO [main]io.seata.common.loader.EnhancedServiceLoader.loadFile:247 -load TransactionStoreManager[FILE] extension by class[io.seata.server.store.file.FileTransactionStoreManager]
2020-04-02 08:36:01.302 INFO [main]io.seata.common.loader.EnhancedServiceLoader.loadFile:247 -load SessionManager[FILE] extension by class[io.seata.server.session.file.FileBasedSessionManager]
# 启动成功
2020-04-02 08:36:01.597 INFO [main]io.seata.core.rpc.netty.RpcServerBootstrap.start:155 -Server started ...
</code></pre>
<ul>
<li>默认配置下，Seata TC Server 启动在 <strong>8091</strong> 端点。</li>
</ul>
<p>因为我们使用 file 模式，所以可以看到用于持久化的本地文件 <code>root.data</code>。操作命令如下：</p>
<pre><code class="language-Bash">$ ls -ls sessionStore/
total 0
0 -rw-r--r--  1 yunai  staff  0 Apr  2 08:36 root.data
</code></pre>
<p>后续，胖友可以阅读<a href="#">「4. 接入 Java 应用」</a>小节，开始使用 Seata 实现分布式事务。</p>
<h1>3. 部署集群 TC Server</h1>
<p>本小节，我们来学习部署<strong>集群</strong> Seata <strong>TC</strong> Server，实现高可用，生产环境下必备。在集群时，多个 Seata TC Server 通过 <strong>db</strong> 数据库，实现全局事务会话信息的共享。</p>
<p>同时，每个 Seata TC Server 可以注册自己到注册中心上，方便应用从注册中心获得到他们。最终我们部署 集群 TC Server 如下图所示：<img src="http://www.iocoder.cn/images/Seata/2017-01-01/21.png" alt="集群 TC Server"></p>
<p>Seata TC Server 对主流的注册中心都提供了集成，具体可见 <a href="https://github.com/seata/seata/tree/develop/discovery">discovery</a> 目录。考虑到国内使用 Nacos 作为注册中心越来越流行，这里我们就采用它。</p>
<blockquote>
<p>友情提示：如果对 Nacos 不了解的胖友，可以参考<a href="http://www.iocoder.cn/Nacos/install/?self">《Nacos 安装部署》</a>文章。</p>
</blockquote>
<p>哔哔完这么多，我们开始正式部署单机 TC Server，这里艿艿使用 macOS 系统，和 Linux、Windows 是差不多的，胖友脑补翻译。</p>
<h2>3.1 下载 Seata 软件包</h2>
<p>打开 <a href="https://github.com/seata/seata/releases">Seata 下载页面</a>，选择想要的 Seata 版本。这里，我们选择 <a href="https://github.com/seata/seata/releases/tag/v1.1.0">v1.1.0</a> 最新版本。</p>
<pre><code class="language-Bash"><span class="hljs-comment"># 创建目录</span>
$ mkdir -p /Users/yunai/Seata
$ <span class="hljs-built_in">cd</span> /Users/yunai/Seata

<span class="hljs-comment"># 下载</span>
$ wget https://github.com/seata/seata/releases/download/v1.1.0/seata-server-1.1.0.tar.gz

<span class="hljs-comment"># 解压</span>
$ tar -zxvf seata-server-1.1.0.tar.gz

<span class="hljs-comment"># 查看目录</span>
$ <span class="hljs-built_in">cd</span> seata
$ ls -ls
24 -rw-r--r--    1 yunai  staff  11365 May 13  2019 LICENSE
 0 drwxr-xr-x    4 yunai  staff    128 Apr  2 07:46 bin <span class="hljs-comment"># 执行脚本</span>
 0 drwxr-xr-x    9 yunai  staff    288 Feb 19 23:49 conf <span class="hljs-comment"># 配置文件</span>
 0 drwxr-xr-x  138 yunai  staff   4416 Apr  2 07:46 lib <span class="hljs-comment">#  seata-*.jar + 依赖库 </span>
</code></pre>
<h2>3.2 初始化数据库</h2>
<p>① 使用 <a href="https://github.com/seata/seata/blob/develop/script/server/db/mysql.sql"><code>mysql.sql</code></a> 脚本，初始化 Seata TC Server 的 db 数据库。脚本内容如下：</p>
<pre><code class="language-SQL"><span class="hljs-comment">-- -------------------------------- The script used when storeMode is 'db' --------------------------------</span>
<span class="hljs-comment">-- the table to store GlobalSession data</span>
<span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> <span class="hljs-keyword">IF</span> <span class="hljs-keyword">NOT</span> <span class="hljs-keyword">EXISTS</span> <span class="hljs-string">`global_table`</span>
(
    <span class="hljs-string">`xid`</span>                       <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">128</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
    <span class="hljs-string">`transaction_id`</span>            <span class="hljs-built_in">BIGINT</span>,
    <span class="hljs-string">`status`</span>                    <span class="hljs-built_in">TINYINT</span>      <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
    <span class="hljs-string">`application_id`</span>            <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">32</span>),
    <span class="hljs-string">`transaction_service_group`</span> <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">32</span>),
    <span class="hljs-string">`transaction_name`</span>          <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">128</span>),
    <span class="hljs-string">`timeout`</span>                   <span class="hljs-built_in">INT</span>,
    <span class="hljs-string">`begin_time`</span>                <span class="hljs-built_in">BIGINT</span>,
    <span class="hljs-string">`application_data`</span>          <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">2000</span>),
    <span class="hljs-string">`gmt_create`</span>                DATETIME,
    <span class="hljs-string">`gmt_modified`</span>              DATETIME,
    PRIMARY <span class="hljs-keyword">KEY</span> (<span class="hljs-string">`xid`</span>),
    <span class="hljs-keyword">KEY</span> <span class="hljs-string">`idx_gmt_modified_status`</span> (<span class="hljs-string">`gmt_modified`</span>, <span class="hljs-string">`status`</span>),
    <span class="hljs-keyword">KEY</span> <span class="hljs-string">`idx_transaction_id`</span> (<span class="hljs-string">`transaction_id`</span>)
) <span class="hljs-keyword">ENGINE</span> = <span class="hljs-keyword">InnoDB</span>
  <span class="hljs-keyword">DEFAULT</span> <span class="hljs-keyword">CHARSET</span> = utf8;

<span class="hljs-comment">-- the table to store BranchSession data</span>
<span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> <span class="hljs-keyword">IF</span> <span class="hljs-keyword">NOT</span> <span class="hljs-keyword">EXISTS</span> <span class="hljs-string">`branch_table`</span>
(
    <span class="hljs-string">`branch_id`</span>         <span class="hljs-built_in">BIGINT</span>       <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
    <span class="hljs-string">`xid`</span>               <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">128</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
    <span class="hljs-string">`transaction_id`</span>    <span class="hljs-built_in">BIGINT</span>,
    <span class="hljs-string">`resource_group_id`</span> <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">32</span>),
    <span class="hljs-string">`resource_id`</span>       <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">256</span>),
    <span class="hljs-string">`branch_type`</span>       <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">8</span>),
    <span class="hljs-string">`status`</span>            <span class="hljs-built_in">TINYINT</span>,
    <span class="hljs-string">`client_id`</span>         <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">64</span>),
    <span class="hljs-string">`application_data`</span>  <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">2000</span>),
    <span class="hljs-string">`gmt_create`</span>        DATETIME(<span class="hljs-number">6</span>),
    <span class="hljs-string">`gmt_modified`</span>      DATETIME(<span class="hljs-number">6</span>),
    PRIMARY <span class="hljs-keyword">KEY</span> (<span class="hljs-string">`branch_id`</span>),
    <span class="hljs-keyword">KEY</span> <span class="hljs-string">`idx_xid`</span> (<span class="hljs-string">`xid`</span>)
) <span class="hljs-keyword">ENGINE</span> = <span class="hljs-keyword">InnoDB</span>
  <span class="hljs-keyword">DEFAULT</span> <span class="hljs-keyword">CHARSET</span> = utf8;

<span class="hljs-comment">-- the table to store lock data</span>
<span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> <span class="hljs-keyword">IF</span> <span class="hljs-keyword">NOT</span> <span class="hljs-keyword">EXISTS</span> <span class="hljs-string">`lock_table`</span>
(
    <span class="hljs-string">`row_key`</span>        <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">128</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
    <span class="hljs-string">`xid`</span>            <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">96</span>),
    <span class="hljs-string">`transaction_id`</span> <span class="hljs-built_in">BIGINT</span>,
    <span class="hljs-string">`branch_id`</span>      <span class="hljs-built_in">BIGINT</span>       <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>,
    <span class="hljs-string">`resource_id`</span>    <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">256</span>),
    <span class="hljs-string">`table_name`</span>     <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">32</span>),
    <span class="hljs-string">`pk`</span>             <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">36</span>),
    <span class="hljs-string">`gmt_create`</span>     DATETIME,
    <span class="hljs-string">`gmt_modified`</span>   DATETIME,
    PRIMARY <span class="hljs-keyword">KEY</span> (<span class="hljs-string">`row_key`</span>),
    <span class="hljs-keyword">KEY</span> <span class="hljs-string">`idx_branch_id`</span> (<span class="hljs-string">`branch_id`</span>)
) <span class="hljs-keyword">ENGINE</span> = <span class="hljs-keyword">InnoDB</span>
  <span class="hljs-keyword">DEFAULT</span> <span class="hljs-keyword">CHARSET</span> = utf8;
</code></pre>
<p>在 MySQL 中，创建 <code>seata</code> 数据库，并在该库下执行该脚本。最终结果如下图：<img src="http://www.iocoder.cn/images/Seata/2017-01-01/22.png" alt=" 数据库 - MySQL 5.X"></p>
<p>② 修改 <code>conf/file</code> 配置文件，修改使用 db 数据库，实现 Seata TC Server 的全局事务会话信息的共享。如下图所示：<img src="http://www.iocoder.cn/images/Seata/2017-01-01/23.png" alt=" 配置文件"></p>
<p>③ MySQL8 的支持</p>
<blockquote>
<p>如果胖友使用的 MySQL 是 8.X 版本，则需要看该步骤。否则，可以直接跳过。</p>
</blockquote>
<p>首先，需要下载 MySQL 8.X JDBC 驱动，命令行操作如下：</p>
<pre><code class="language-Bash">$ <span class="hljs-built_in">cd</span> lib
$ wget https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.19/mysql-connector-java-8.0.19.jar
</code></pre>
<p>然后，修改 <code>conf/file</code> 配置文件，使用该 MySQL 8.X JDBC 驱动。如下图所示：<img src="http://www.iocoder.cn/images/Seata/2017-01-01/24.png" alt=" 数据库 - MySQL 8.X"></p>
<h2>3.3 设置使用 Nacos 注册中心</h2>
<p>修改 <code>conf/registry.conf</code> 配置文件，设置使用 Nacos 注册中心。如下图所示：<img src="http://www.iocoder.cn/images/Seata/2017-01-01/25.png" alt=" 配置文件"></p>
<h2>3.4 启动 TC Server</h2>
<p>① 执行 <code>nohup sh bin/seata-server.sh -p 18091 -n 1 &amp;</code> 命令，启动<strong>第一个</strong> TC Server 在后台。</p>
<ul>
<li><code>-p</code>：Seata TC Server 监听的端口。</li>
<li><code>-n</code>：Server node。在多个 TC Server 时，需区分各自节点，用于生成不同区间的 transactionId 事务编号，以免冲突。</li>
</ul>
<p>在 <code>nohup.out</code> 文件中，我们看到如下日志，说明启动成功：</p>
<pre><code class="language-Java"># 使用 DB 存储器
2020-04-05 16:54:12.793 INFO [main]io.seata.common.loader.EnhancedServiceLoader.loadFile:247 -load DataSourceGenerator[dbcp] extension by class[io.seata.server.store.db.DbcpDataSourceGenerator]
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
2020-04-05 16:54:13.442 INFO [main]io.seata.common.loader.EnhancedServiceLoader.loadFile:247 -load LogStore[DB] extension by class[io.seata.core.store.db.LogStoreDataBaseDAO]
2020-04-05 16:54:13.442 INFO [main]io.seata.common.loader.EnhancedServiceLoader.loadFile:247 -load TransactionStoreManager[DB] extension by class[io.seata.server.store.db.DatabaseTransactionStoreManager]
2020-04-05 16:54:13.442 INFO [main]io.seata.common.loader.EnhancedServiceLoader.loadFile:247 -load SessionManager[DB] extension by class[io.seata.server.session.db.DataBaseSessionManager]
# 启动成功
2020-04-05 16:54:13.779 INFO [main]io.seata.core.rpc.netty.RpcServerBootstrap.start:155 -Server started ...
# 使用 Nacos 注册中心
2020-04-05 16:54:13.788 INFO [main]io.seata.common.loader.EnhancedServiceLoader.loadFile:247 -load RegistryProvider[Nacos] extension by class[io.seata.discovery.registry.nacos.NacosRegistryProvider]
</code></pre>
<p>② 执行 <code>nohup sh bin/seata-server.sh -p 28091 -n 2 &amp;</code> 命令，启动<strong>第二个</strong> TC Server 在后台。</p>
<p>③ 打开 Nacos 注册中心的控制台，我们可以看到有<strong>两个</strong> Seata TC Server 示例。如下图所示：<img src="http://www.iocoder.cn/images/Seata/2017-01-01/26.png" alt="Nacos 控制台"></p>
<h1>4. 接入 Java 应用</h1>
<h2>4.1 AT 模式</h2>
<p><strong>① Spring Boot</strong></p>
<p>1、<a href="http://www.iocoder.cn/Spring-Boot/Seata/?self">《芋道 Spring Boot 分布式事务 Seata 入门》</a>的<a href="#">「2. AT 模式 + 多数据源」</a>小节，实现单体 Spring Boot 项目在多数据源下的分布式事务。</p>
<p><img src="http://www.iocoder.cn/images/Spring-Boot/2020-10-01/01.png" alt="整体图"></p>
<p>2、<a href="http://www.iocoder.cn/Spring-Boot/Seata/?self">《芋道 Spring Boot 分布式事务 Seata 入门》</a>的<a href="#">「AT 模式 + HttpClient 远程调用」</a>小节，实现多个 Spring Boot 项目的分布事务。</p>
<p><img src="http://www.iocoder.cn/images/Spring-Boot/2020-10-01/21.png" alt="整体图"></p>
<p><strong>② Dubbo</strong></p>
<p><a href="http://www.iocoder.cn/Dubbo/Seata/?sef">《Dubbo 分布式事务 Seata 入门》</a>的<a href="#">「2. AT 模式」</a>小节，实现多个 Dubbo 服务下的分布式事务。</p>
<p><img src="http://www.iocoder.cn/images/Dubbo/2020-04-15/01.png" alt="整体图"></p>
<p><strong>③ Spring Cloud</strong></p>
<p><a href="http://www.iocoder.cn/Spring-Cloud-Alibaba/Seata/?self">《芋道 Spring Cloud Alibaba 分布式事务 Seata 入门》</a>的<a href="#">「3. AT 模式 + Feign」</a>小节，实现多个 Spring Cloud 服务下的分布式事务。</p>
<p><img src="http://www.iocoder.cn/images/Spring-Cloud/2020-07-15/01.png" alt="整体图"></p>
<h2>4.2 TCC 模式</h2>
<ul>
<li>文档：<a href="http://127.0.0.1:8080/zh-cn/docs/dev/mode/tcc-mode.html">《Seata 文档 —— TCC 模式》</a></li>
<li>示例：<a href="https://github.com/seata/seata-samples/blob/master/tcc">https://github.com/seata/seata-samples/blob/master/tcc</a></li>
</ul>
<h2>4.3 Saga 模式</h2>
<ul>
<li>文档：<a href="https://seata.io/zh-cn/docs/dev/mode/saga-mode.html">《Seata 文档 —— Saga 模式》</a></li>
<li>示例：<a href="https://github.com/seata/seata-samples/tree/master/saga">https://github.com/seata/seata-samples/tree/master/saga</a></li>
</ul>
<h2>4.4 XA 模式</h2>
<p>Seata 正在开发中...</p>
</section><footer class="footer-container"><div class="footer-body"><img src="//img.alicdn.com/tfs/TB1dGrSwVT7gK0jSZFpXXaTkpXa-4802-1285.png"/><p class="docsite-power">website powered by docsite</p><div class="cols-container"><div class="col col-12"><h3>愿景</h3><p>Seata 是一款阿里巴巴开源的分布式事务解决方案，致力于在微服务架构下提供高性能和简单易用的分布式事务服务。</p></div><div class="col col-6"><dl><dt>文档</dt><dd><a href="/zh-cn/docs/overview/what-is-seata.html" target="_self">Seata 是什么？</a></dd><dd><a href="/zh-cn/docs/user/quickstart.html" target="_self">快速开始</a></dd><dd><a href="https://github.com/seata/seata.github.io/issues/new" target="_self">报告文档问题</a></dd><dd><a href="https://github.com/seata/seata.github.io" target="_self">在Github上编辑此文档</a></dd></dl></div><div class="col col-6"><dl><dt>资源</dt><dd><a href="/zh-cn/blog/index.html" target="_self">博客</a></dd><dd><a href="/zh-cn/community/index.html" target="_self">社区</a></dd></dl></div></div><div class="copyright"><span>Copyright © 2019 Seata</span></div></div></footer></div></div>
	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
	<script>
		window.rootPath = '';
  </script>
	<script src="/build/blogDetail.js"></script>
	<script>
    var _hmt = _hmt || [];
    (function() {
      var hm = document.createElement("script");
      hm.src = "https://hm.baidu.com/hm.js?104e73ef0c18b416b27abb23757ed8ee";
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(hm, s);
    })();
    </script>
</body>
</html>
